<

デスクトップ上のデフォルトの「PrimaryScrollController」

まとめ

PrimaryScrollControllerAPI が自動的に更新されなくなりました 垂直に取り付けるScrollViewデスクトッププラットフォーム上で。

コンテクスト

この変更の前は、ScrollView.primaryの場合、デフォルトは true になります。ScrollView持っていたAxis.verticalスクロール方向とScrollControllerすでに提供されていませんでした。これにより、次のような一般的な UI パターンが可能になりました。 iOS の上部へのスクロール機能は、Flutter アプリですぐに使用できます。 ただし、デスクトップでは、このデフォルトにより、次のアサーション エラーが発生することがよくあります。

ScrollController attached to multiple ScrollViews.

モバイル アプリケーションで表示されるのは一般的ですが、ScrollView一度に、 デスクトップ UI パターンは複数表示される可能性が高くなります。ScrollViews 並んで。以前の実装では、PrimaryScrollController矛盾した このパターンでは、役に立たないエラー メッセージが表示されることがよくあります。これを解決するには、 のPrimaryScrollController追加パラメータで更新されました また、それに依存する複数のウィジェット間でのエラー メッセージングも改善されます。

変更内容の説明

以前の実装ScrollViewをもたらしましたprimary~によって真実であること すべての垂直方向のデフォルトScrollViewまだ持っていないScrollController、すべてのプラットフォームで。このデフォルトの動作は必ずしも明確ではありませんでした。 特にそれは別のものであるため、PrimaryScrollController自体。

// Previously, this ListView would always result in primary being true,
// and attached to the PrimaryScrollController on all platforms.
Scaffold(
  body: ListView.builder(
    itemBuilder: (BuildContext context, int index) {
      return Text('Item $index');
    }
  ),
);

実装の変更ScrollView.primaryフォールバックを使用して null 可能にする 意思決定はPrimaryScrollController。 いつprimarynull、または noScrollControllerが提供されており、ScrollView調べてみますPrimaryScrollControllerそして代わりに電話してくださいshouldInheritに 与えられたかどうかを判断しますScrollViewを使用する必要がありますPrimaryScrollController

の新しいメンバーは、PrimaryScrollControllerクラス、automaticallyInheritForPlatformsscrollDirection、で評価されますshouldInherit、ユーザーが明確に制御できるようにします。PrimaryScrollControllerの行動。

デフォルトでは、モバイル プラットフォームに対して下位互換性が維持されます。PrimaryScrollController.shouldInherit垂直方向の場合は true を返しますScrollViews.デスクトップでは、デフォルトで false が返されます。

// Only on mobile platforms will this attach to the PrimaryScrollController by
// default.
Scaffold(
  body: ListView.builder(
    itemBuilder: (BuildContext context, int index) {
      return Text('Item $index');
    }
  ),
);

デフォルトを変更するには、ユーザーが設定できますScrollView.primary真か偽か 明示的に管理するPrimaryScrollController個人にとってScrollView。 複数にわたる動作の場合ScrollViews、PrimaryScrollController今でしょ 特定のプラットフォームとスクロール方向を設定することで構成可能 それは継承にとって好ましいものです。

を使用するウィジェットPrimaryScrollController、 そのようなNestedScrollViewScrollbar、 とDropdownMenuButton既存のものに変更はありません 機能性。 iOS のスクロールトップなどの機能も引き続き機能します。 移行なしで期待されます。

ScrollActionScrollIntentデスクトップ上の は、影響を受ける唯一のクラスです。 この変更には移行が必要です。デフォルトでは、PrimaryScrollControllerは フォールバックキーボードスクロールを実行するために使用されますShortcuts現在の場合Focusは 内に含まれるScrollable。複数表示してるのでScrollViewデスクトップ プラットフォームではサイドバイサイドが一般的ですが、 ときめいて決めるScrollViewこのビューではプライマリにして受信する必要があります キーボードのスクロールアクションは?

複数の場合ScrollViewこの変更の前にも存在していましたが、同じです アサーション(ScrollController attached to multiple ScrollViews.) がスローされます。 現在、デスクトップ プラットフォームでは、ユーザーは次のことを指定する必要があります。primary: trueに どちらを指定するかScrollView未処理のキーボードを受け取るためのフォールバックですShortcuts

移行ガイド

移行前のコード:

// These side-by-side ListViews would throw errors from Scrollbars and
// ScrollActions previously due to the PrimaryScrollController.
Scaffold(
  body: LayoutBuilder(
    builder: (context, constraints) {
      return Row(
        children: [
          SizedBox(
            height: constraints.maxHeight,
            width: constraints.maxWidth / 2,
            child: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return Text('List 1 - Item $index');
              }
            ),
          ),
          SizedBox(
            height: constraints.maxHeight,
            width: constraints.maxWidth / 2,
            child: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return Text('List 2 - Item $index');
              }
            ),
          ),
        ]
      );
    },
  ),
);

移行後のコード:

// These side-by-side ListViews will no longer throw errors, but for
// default ScrollActions, one will need to be designated as primary.
Scaffold(
  body: LayoutBuilder(
    builder: (context, constraints) {
      return Row(
        children: [
          SizedBox(
            height: constraints.maxHeight,
            width: constraints.maxWidth / 2,
            child: ListView.builder(
              // This ScrollView will use the PrimaryScrollController
              primary: true,
              itemBuilder: (BuildContext context, int index) {
                return Text('List 1 - Item $index');
              }
            ),
          ),
          SizedBox(
            height: constraints.maxHeight,
            width: constraints.maxWidth / 2,
            child: ListView.builder(
              itemBuilder: (BuildContext context, int index) {
                return Text('List 2 - Item $index');
              }
            ),
          ),
        ]
      );
    },
  ),
);

タイムライン

リリースされたバージョン: 3.3.0-0.0.pre
安定版リリース: 3.3

参考文献

API ドキュメント:

  • PrimaryScrollController
  • ScrollView
  • ScrollAction
  • ScrollIntent
  • Scrollbar

設計書:

  • PrimaryScrollController の更新

関連する問題:

  • 問題 #100264

関連する PR:

  • デスクトップ用 PrimaryScrollController の更新